# hApplyFrequencyDomainChannel Apply frequency domain channel to resource grid 
#   [RXGRID, H, OFFSET] = 
#   hApplyFrequencyDomainChannel(CARRIER, PATHGAINS, PATHFILTERS, SAMPLETIMES, TXGRID, OFFSET) 
#   applies a frequency domain channel to the resource grid TXGRID, returning 
#   the received resource grid RXGRID, perfect channel estimate H and the  
#   channel filter delay OFFSET. CARRIER is the carrier configuration.
#   PATHGAINS is the path gains obtained from the channel. PATHFILTERS is the 
#   path filters obtained from the channel. SAMPLETIMES is the sample times 
#   obtained from the channel. OFFSET is an optional input of the channel 
#   filter delay. If provided, it is used instead of calculating the perfect 
#   timing estimate.

# Copyright 2023 The MathWorks, Inc.


function hApplyFrequencyDomainChannel(carrier, pathGains, pathFilters, sampleTimes, txGrid, offset=nothing)
    # 手动实现时序估计
    if isnothing(offset)
        # 使用互相关进行时序估计
        offset = estimateTiming(pathGains, pathFilters)
    end

    # 手动实现信道估计
    H = estimateChannel(carrier, pathGains, pathFilters, offset, sampleTimes)

    # 调整 H 的大小以与 txGrid 匹配
    H = H[:, 1:size(txGrid, 2), :, :]

    # 应用信道矩阵
    rxGrid = applyChannelMatrices(txGrid, H)
    
    return rxGrid, H, offset
end

# 手动时序估计
function estimateTiming(pathGains, pathFilters)
    # 使用互相关来估计时序偏移
    # 假设 pathGains 包含了信号的导频信息
    # 这里简单地计算 pathGains 与 pathFilters 的互相关来估算时序偏移
    crossCorr = xcorr(pathGains[:], pathFilters[:])
    peakIndex = argmax(abs(crossCorr))  # 找到互相关的最大值
    offset = peakIndex - length(pathFilters)  # 计算时序偏移
    return offset
end

# 手动信道估计
function estimateChannel(carrier, pathGains, pathFilters, offset, sampleTimes)
    # 假设 pathGains 是信道增益数据，pathFilters 是滤波器
    # 这里我们简单地用 pathGains 作为信道增益并进行插值
    
    # 插值：这里我们用路径增益进行插值来估算信道
    # 简单的线性插值，替换为实际信道估计方法
    NSub, NSym, NRxAnt, NPath = size(pathGains)
    H = zeros(NSub, NSym, NRxAnt, NPath)
    
    for sub in 1:NSub
        for sym in 1:NSym
            for rxAnt in 1:NRxAnt
                for path in 1:NPath
                    # 进行简单的增益插值来估算信道
                    H[sub, sym, rxAnt, path] = pathGains[sub, sym, rxAnt, path] * pathFilters[path, sym]
                end
            end
        end
    end
    return H
end

# 应用信道矩阵
function applyChannelMatrices(in, H)
    # 计算输出信号
    out = sum(H .* permutedims(in, (1, 2, 4, 3)), dims=4)  # 在第 4 维上求和
    return out
end
